home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / Finder Progress Bar / Finder ProgressBar.c next >
Encoding:
C/C++ Source or Header  |  1993-08-28  |  8.0 KB  |  250 lines  |  [TEXT/KAHL]

  1. /*****************************************************************************************************
  2. *                                                                                                    *
  3. * Finder ProgressBar.c - Copyright 1993 Chris Larson (cklarson@engr.ucdavis.edu) All rights reserved *
  4. *                                                                                                    *
  5. * Source file of a CDEF which mimics the progress bar used in the Finder. This source file and its   *
  6. * compiled derivatives may be freely used within any freeware/shareware/postcardware/beerware/… as   *
  7. * long as you mention my name in your credits. Neither this source nor its compiled derivatives are  *
  8. * in the public domain and may not be use in any form in public domain software. Neither this source *
  9. * nor its compiled derivatives may be used in any form in a commercial product without the expressed,*
  10. * written consent of the author (me).                                                                *
  11. *                                                                                                    *
  12. * Version 1.0 -- Initial Release.                                                                    *
  13. *                                                                                                    *
  14. *****************************************************************************************************/
  15.  
  16. #include "Finder ProgressBar.h"
  17.  
  18. //----------------------------------------------------------------------------------------------------
  19. //
  20. // main -- Handle everything but draw messages.
  21. //
  22. //----------------------------------------------------------------------------------------------------
  23.  
  24. pascal long main (short varCode, ControlHandle theControlHandle, short message, long param)
  25. {
  26.     SignedByte    controlRecState;    // Holds the state of the control record’s handle.
  27.     long        returnValue;        // Holds the value returned by the CDEF.
  28.     ControlPtr    theControl;            // Holds a pointer to the control record.
  29.     
  30.     // ----------
  31.     // Since I use some static local variables within the draw routine, a4 must be ‘set up’
  32.     // (read: made to point to the top of the CDEF) to access global and static variables.
  33.     // This routine simply saves the value of a4 and points a4 to the top of the CDEF
  34.     // (this address is put into a0 by the header so I simply read it from there). See the
  35.     // header file for details.
  36.     // ----------
  37.     
  38.     MySetUpA4();
  39.     
  40.     // ----------
  41.     // Lock down the control record.
  42.     // ----------
  43.     
  44.     controlRecState = HGetState((Handle)theControlHandle);
  45.     HLock((Handle)theControlHandle);
  46.     
  47.     // ----------
  48.     // Initialize the return value and the control pointer (since the record is locked it is safe
  49.     // to use a pointer). The return value is initialized to 0 since most CDEF messages want 0
  50.     // returned.
  51.     // ----------
  52.     
  53.     returnValue = 0;
  54.     theControl = *theControlHandle;
  55.     
  56.     switch (message)
  57.         {
  58.         
  59.         // ----------
  60.         // Ignore draw messages if the control is not visible.
  61.         // ----------
  62.         
  63.         case drawCntl:
  64.             if (theControl->contrlVis)
  65.                 DrawProgressBar(theControlHandle);
  66.             break;
  67.         
  68.         // ----------
  69.         // Test the control: return 1 if the give point is within the control's rectangle
  70.         // and the control is not dimmed, 0 otherwise (the whole bar is part #1).
  71.         // ----------
  72.         
  73.         case testCntl:
  74.             if (theControl->contrlHilite != 0xFF)
  75.                 returnValue = PtInRect(*(Point*)(¶m),&(theControl->contrlRect));
  76.             break;
  77.         
  78.         // ----------
  79.         // For the 24-bit mode region calculation message, the high bit of the given region handle
  80.         // must be cleared. Note that I don’t test this bit to determine which region to calculate.
  81.         // Since this control has no indicator (part with a part code >= 129) I will never receive
  82.         // a message asking for indicator region calculation.
  83.         // ----------
  84.         
  85.         case calcCRgns:
  86.             param &= 0x7FFFFFFF;
  87.         
  88.         // ----------
  89.         // Calculate the control’s region.
  90.         // ----------
  91.         
  92.         case calcCntlRgn:
  93.             RectRgn((RgnHandle)param,&(theControl->contrlRect));
  94.             break;
  95.         
  96.         // ----------
  97.         // All other messages do nothing and return 0.
  98.         // ----------
  99.         
  100.         default:
  101.             break;
  102.         }
  103.     
  104.     // ----------
  105.     // Restore the state of the control record’s handle.
  106.     // ----------
  107.     
  108.     HSetState ((Handle)theControlHandle, controlRecState);
  109.     
  110.     // ----------
  111.     // Restore the value of a4 from its saved location.
  112.     // ----------
  113.     
  114.     MyRestoreA4();
  115.     
  116.     // ----------
  117.     // We’re outa here.
  118.     // ----------
  119.     
  120.     return (returnValue);
  121. }
  122.  
  123. //----------------------------------------------------------------------------------------------------
  124. //
  125. // DrawProgressBar -- Draw the control according to the values within the control record.
  126. //
  127. //----------------------------------------------------------------------------------------------------
  128.  
  129. void DrawProgressBar (ControlHandle theControlHandle)
  130. {
  131.     PenState        oldPen;
  132.     RGBColor        oldFore, oldBack;
  133.     static RGBColor    blackColor = cBlack, whiteColor = cWhite, blueColor = cBlue, grayColor = cGray;
  134.     RgnHandle        oldClip,currentClip;
  135.     ControlPtr        theControl = *theControlHandle;
  136.     Rect            theBox = theControl->contrlRect;
  137.     GrafPtr            savePort, controlPort = theControl->contrlOwner;
  138.     
  139.     // ----------
  140.     // Set the port to the control’s port. Very probably not needed (since Apple’s CDEFs do not
  141.     // do this) but just to be extra safe…
  142.     // ----------
  143.     
  144.     GetPort (&savePort);
  145.     SetPort (controlPort);
  146.     
  147.     // ----------
  148.     // Save the current port’s clip region and set it to the intersection of the clip region with
  149.     // the control’s rectangle.
  150.     // ----------
  151.     
  152.     oldClip = NewRgn();
  153.     GetClip(oldClip);
  154.     
  155.     ClipRect(&(theControl->contrlRect));
  156.     currentClip = theControl->contrlOwner->clipRgn;
  157.     SectRgn(currentClip,oldClip,currentClip);
  158.     
  159.     // ----------
  160.     // Save and reset the pen state
  161.     // ----------
  162.     
  163.     GetPenState(&oldPen);
  164.     PenNormal();
  165.     
  166.     // ----------
  167.     // If we have color QD, save the foreground and background colors and set the foreground color
  168.     // to black, background color to white.
  169.     // ----------
  170.     
  171.     if ( (ROM85 & kNoColorQD) == 0 )
  172.         {
  173.         GetForeColor(&oldFore);
  174.         GetBackColor(&oldBack);
  175.         
  176.         RGBForeColor(&blackColor);
  177.         RGBBackColor(&whiteColor);
  178.         }
  179.     
  180.     // ----------
  181.     // Draw the progress bar frame and set up the rectangle for drawing the bar.
  182.     // ----------
  183.     
  184.     FrameRect(&theBox);
  185.     InsetRect(&theBox,1,1);
  186.     
  187.     // ----------
  188.     // CalcBarBoundry is an inline function that returns the value described by the equation
  189.     // theBox.left + ( controlValue * (theBox.right - theBox.left) )/(controlMax - controlMin).
  190.     // This is implemented as an inline function to avoid using the glue for 32-bit multiplication
  191.     // and division that is necessary on the 68000 (the glue is not really needed for this
  192.     // calculation and it more than doubles the size of the CDEF when included, so I rolled my
  193.     // own).
  194.     // ----------
  195.     
  196.     theBox.right = CalcBarBoundry(&theBox,theControl);
  197.     
  198.     // ----------
  199.     // If we have color, set the foreground color to gray, leave the background white so that
  200.     // the gray will map to black on a 1-bit monitor. Note that for non-color QD machines, we want
  201.     // the bar to be black. Since the PenNormal() call set the pen pattern to black, we need do
  202.     // nothing. Then draw the bar.
  203.     // ----------
  204.     
  205.     if ( (ROM85 & kNoColorQD) == 0 )
  206.         RGBForeColor(&grayColor);
  207.  
  208.     PaintRect(&theBox);
  209.     
  210.      // ----------
  211.      // Set up the rectangle to describe the space from the end of the bar to the edge of the
  212.      // inset rectangle.
  213.      // ----------
  214.      
  215.     theBox.left = theBox.right;
  216.     theBox.right = (theControl->contrlRect.right) - 1;
  217.  
  218.     // ----------
  219.     // If we have color, set the foreground to blue and the background to black (so that the blue
  220.     // will map to white on a 1-bit monitor). If no color, we want to erase the empty space, so
  221.     // set the pen to erase. Then paint the rectangle.
  222.     // ----------
  223.  
  224.     if ( (ROM85 & kNoColorQD) == 0 )
  225.         {
  226.         RGBForeColor(&blueColor);
  227.         RGBBackColor(&blackColor);
  228.         }
  229.     else
  230.         PenMode(patBic);
  231.     
  232.     PaintRect(&theBox);
  233.     
  234.     // ----------
  235.     // Restore all the stuff we munged: colors, pen state, clip region, and current port.
  236.     // ----------
  237.     
  238.     if ( (ROM85 & kNoColorQD) == 0 )
  239.         {
  240.         RGBForeColor(&oldFore);
  241.         RGBBackColor(&oldBack);
  242.         }
  243.     
  244.     SetPenState(&oldPen);
  245.     
  246.     SetClip(oldClip);
  247.     DisposeRgn(oldClip);
  248.     
  249.     SetPort(savePort);
  250. }